package com.syzg.base.login.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.syzg.base.aduit.config.AuditConfig;
import com.syzg.base.aduit.model.Audit;
import com.syzg.base.aduit.service.AuditService;
import com.syzg.base.login.model.LoginObject;
import com.syzg.base.login.service.LoginService;
import com.syzg.base.merge.model.Module;
import com.syzg.base.merge.model.Person;
import com.syzg.base.module.service.ModuleService;
import com.syzg.base.permission.service.PermissionService;
import com.syzg.base.person.service.PersonService;
import com.syzg.common.config.SysProperties;
import com.syzg.common.model.WebInfo;
import com.zenithsun.common.security.csrf.CSRFTokenManager;
import com.zenithsun.common.util.DateUtils;
import com.zenithsun.common.util.WebUtil;

@Controller
public class LoginController {

	@Resource
	private LoginService loginService;
	@Resource
	private ModuleService moduleService;
	@Resource
	private PermissionService permissionService;

	@Resource
	private PersonService personService;
	@Resource
	private AuditService auditService;
	
	@RequestMapping("/login")
	public String loginInput(HttpServletRequest request) {
		/******是否已经登录**************/
		/******当前用户**************/
		Object currentLogin = request.getSession().getAttribute(SysProperties.USER_SESSION_KEY);
		if(currentLogin != null){
			//已经登录直接跳转至工作台
			return "/baseNew/index.jsp";
		}
		
		return "/zenithsun/login/login.jsp";
	}

	@RequestMapping("/loginSys")
	public ModelAndView login(String txt_account, String txt_password, String verifyCode,HttpServletRequest request) throws Exception {
		//是否已登录
		if(request.getSession().getAttribute(SysProperties.USER_SESSION_KEY) != null){
			return new ModelAndView("/baseNew/index.jsp");
		}
		/** CSRF token **/
		//CSRFTokenManager.validateForm(request);	
		boolean flag = CSRFTokenManager.validateToken(request);
		
		HttpSession session = request.getSession();
		WebInfo webInfo = new WebInfo();
		ModelAndView mv = new ModelAndView("/zenithsun/login/login.jsp");
		
		/******是否跨站请求**************/
		if(!flag){
			webInfo.addInfo("跨站点请求被拒绝！");
			return mv;
		}
		/** login **/
		mv.addObject("webInfo", webInfo);
		LoginObject loginObject = null;
		Person p = new Person();
		p.setAccount(txt_account);
		Person person = personService.findPerson(p);
		//验证账号是否正确
		if (person != null) {
			/**#########  判断当前账号是否被锁定，锁定时间是否已过，未过禁止登录  ############**/
			if(person.getLockedTime() != null){
				//获取配置中的锁定时间 默认30min，可调整
				long lockedTime =  SysProperties.LOGIN_FAILURE_LOCKED_TIME;
				long diffTime = new Date().getTime() - person.getLockedTime().getTime();
				diffTime = diffTime / (1000 * 60);
				if(diffTime < lockedTime){
					//锁定中
					webInfo.addInfo("账户已被锁定，" +(lockedTime - diffTime)+"分钟后解锁");
					return mv;
				}
			}
			//判断验证码
			if (SysProperties.LOGIN_CAPTCHA) {
				String verifyCodeSession = (String) session.getAttribute("VERIFY_CODE");
				if (verifyCode == null || !verifyCode.equals(verifyCodeSession)) {
					webInfo.addInfo("验证码错误");
					return mv;
				}
			}
			//当前终端IP
			String currentIP = WebUtil.getIpAddr(request);
			//初始化审计日志
			Audit audit = new Audit(person,"登录系统",AuditConfig.TYPE_LOGIN,currentIP);
			//验证用户名密码
			Object object = loginService.checkLogin(txt_account, txt_password);
			if (object instanceof LoginObject) {
				loginObject = (LoginObject) object;
				loginObject.setIp(currentIP);
				loginObject.setSessionId(session.getId());
				loginObject.setLoginDate(DateUtils.formatCurrentDateTime());
				session.setAttribute(SysProperties.USER_SESSION_KEY, loginObject);
				//获取权限
				if (SysProperties.ADMIN_LOGIN.equals(loginObject.getLogin())) {
					List<Module> listModule = moduleService.findModules();
					session.setAttribute(SysProperties.PERSON_MODULE_LIST, listModule);
				} else {
					session.setAttribute(SysProperties.PERSON_MODULE_LIST,permissionService.findModulesByPersonId(loginObject.getPersonId()));
				}
				//清除锁定信息
				if(person.getLoginFailureTimes() != 0){
					person.setLoginFailureTimes(0);
					person.setLockedTime(null);
					personService.updatePerson(person);
				}
				//session 记录当前person
				session.setAttribute("CURRENT_PERSON", person);
				session.setAttribute("SYSTEM_TYPE", SysProperties.SYSTEM_TYPE);
				//记录登录成功日志
				audit.setFlag(AuditConfig.OP_SUCCESS);
				mv.setViewName("/baseNew/index.jsp");
			} else if (object == null) {
					/**###################用户登录失败处理 #########################**/
					/** 修改锁定次数                                                                                                                              **/
					/**LOGIN_FAILURE_TIMES : 允许连续登录失败的次数                                              **/
					/**LOGIN_FAILURE_LOCKED_TIME : 超过允许连续登录失败的次数锁定时间 **/
					person.setLoginFailureTimes(person.getLoginFailureTimes() + 1);
					if (person.getLoginFailureTimes() == SysProperties.LOGIN_FAILURE_TIMES) {
						person.setLockedTime(new Date());
						webInfo.addInfo("账号已被锁定，请"+(SysProperties.LOGIN_FAILURE_LOCKED_TIME)+"分钟后再尝试");
					}else{
						webInfo.addInfo("密码不正确，还剩余"+(SysProperties.LOGIN_FAILURE_TIMES - person.getLoginFailureTimes())+"次机会");
					}
					personService.updatePerson(person);
					audit.setFlag(AuditConfig.OP_FAILURE);
					/**###################登录失败处理 end##########################################**/
			} else { // 其他错误
				webInfo.addInfo((String) object);
			}
			//记录日志
			auditService.create(audit);
		}else{
			webInfo.addInfo("帐号不正确");
		}
		return mv;
	}

	/**
	 * 登出
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping("/logout")
	public ModelAndView logout(HttpServletRequest request) throws Exception {
		HttpSession session = request.getSession();
		ModelAndView mv = new ModelAndView("/zenithsun/login/login.jsp");
		//注销日志
		Audit audit = new Audit("注销系统", AuditConfig.TYPE_LOGOUT,AuditConfig.OP_SUCCESS, request);
		LoginObject loginObject = (LoginObject)request.getSession().getAttribute(SysProperties.USER_SESSION_KEY);
		if(loginObject != null)
		{
			//清除记录的session 
			if(SysProperties.LOGIN_SINGLE){
				ServletContext sc = request.getServletContext();
				Object obj = sc.getAttribute(SysProperties.USER_ONLINE_LIST);
				Map<String, LoginObject> map;
				if(obj != null){
					map = (HashMap<String, LoginObject>) obj;
					if(map.containsKey(loginObject.getLogin())){
						map.remove(loginObject.getLogin());
						sc.setAttribute(SysProperties.USER_ONLINE_LIST, map);
					}
				}
				String sessionId = loginObject.getSessionId();
				if(sc.getAttribute(SysProperties.USER_SESSION_LIST) != null)
				{
					Map<String, HttpSession> sessionList = (HashMap<String, HttpSession>)
							sc.getAttribute(SysProperties.USER_SESSION_LIST);
					sessionList.remove(sessionId);
					sc.setAttribute(SysProperties.USER_SESSION_LIST,sessionList);
				}
			}
			session.invalidate();
			auditService.create(audit);
		}
		return mv;
	}
	/**
	 * 强制下线
	 * @param loginId
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping(value ="/offline",produces="application/json;utf-8")
	@ResponseBody
	public String offline(String loginId,HttpServletRequest request){
		Map<String, Object> msg = new HashMap<String, Object>();
		try {
			Object currentSession = request.getSession().getAttribute(SysProperties.USER_SESSION_KEY) ;
			if(currentSession != null){
				LoginObject loginObject = (LoginObject) currentSession;
				if(loginId.equals(loginObject.getLogin())){
					msg.put("success", false);
					msg.put("content", "NOT OFF SELF");
				}else{
					ServletContext sc = request.getServletContext();
					Object obj = sc.getAttribute(SysProperties.USER_ONLINE_LIST);
					Map<String, LoginObject> userMap;
					if(obj != null){
						userMap = (HashMap<String, LoginObject>) obj;
						if(userMap.containsKey(loginId)){
							//处理用户列表
							LoginObject lo = userMap.get(loginId);
							userMap.remove(loginId);
							sc.setAttribute(SysProperties.USER_ONLINE_LIST, userMap);
							
							//处理session 列表
							Map<String, HttpSession> sessionList = (HashMap<String, HttpSession>)sc.getAttribute(SysProperties.USER_SESSION_LIST);
							HttpSession oldSession = sessionList.get(lo.getSessionId());
							if(oldSession != null){
								oldSession.invalidate();
							}
							sessionList.remove(lo.getSessionId());
							sc.setAttribute(SysProperties.USER_SESSION_LIST,sessionList);
						}
					}
					msg.put("success", true);
					msg.put("content", "YES");
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			msg.put("success", false);
			msg.put("content", "ERROR");
		}
		return JSON.toJSONString(msg);
	}
	@SuppressWarnings("unchecked")
	@RequestMapping(value ="/lineList")
	public ModelAndView lineList(HttpServletRequest request){
		ModelAndView mv = new ModelAndView("/zenithsun/login/lineList.jsp");
		ServletContext sc = request.getServletContext();
		Map<String, LoginObject> userList = (HashMap<String, LoginObject>) sc.getAttribute(SysProperties.USER_ONLINE_LIST);
		List<LoginObject> lineList = new ArrayList<>();
		for (String key : userList.keySet()) {
			lineList.add(userList.get(key));
		}
		mv.addObject("lineList",lineList);
		return mv;
	}
}
